Deny partial -Z stack-protector by default in all editions - #157941
Deny partial -Z stack-protector by default in all editions#157941arielb1 wants to merge 1 commit into
-Z stack-protector by default in all editions#157941Conversation
This comment has been minimized.
This comment has been minimized.
cffa608 to
1a9ed85
Compare
This comment has been minimized.
This comment has been minimized.
1a9ed85 to
5e3dc2c
Compare
This comment has been minimized.
This comment has been minimized.
5e3dc2c to
42cf0c9
Compare
This comment has been minimized.
This comment has been minimized.
42cf0c9 to
7312a2c
Compare
|
Some changes occurred in tests/codegen-llvm/stack-protector.rs cc @rust-lang/project-exploit-mitigations, @rcvalle |
This enables RFC 3855 for stack-protector. With this PR, uses of stack-protector that only have it enabled for a subset of the crates within a process need to pass `-Z allow-partial-mitigations=stack-protector` as well. This was not done in issue 149357 to allow for a smooth transition period. cc the stack-protector tracking issue at issue 114903.
7312a2c to
5edba65
Compare
|
☔ The latest upstream changes (presumably #159246) made this pull request unmergeable. Please resolve the merge conflicts by rebasing. |
…coverage (#314) * harden: /CETCOMPAT (backward-edge CFI) + machine-enforced mitigation coverage Two additions, both from the nightly-feature research, and both made ENFORCED rather than merely set — a mitigation we asked for is not a mitigation we have. /CETCOMPAT — the missing half of control-flow integrity. `control-flow-guard=checks` has protected indirect CALLS since the beginning; nothing protected RETURNS. /CETCOMPAT marks the image compatible with the CPU's hardware shadow stack, which keeps a protected copy of return addresses and faults on divergence. That is the direct answer to ROP, which CFG does not address. * STABLE — a plain linker flag, no nightly needed. * Measured cost: 0 bytes. * COMPATIBILITY, since it is a fair question: it is a MARK, not a requirement. Microsoft's docs describe it as telling the linker to "mark the binary as CET Shadow Stack- compatible". Windows enables shadow stacks only where CPU and OS support them AND the image opts in; on hardware without CET there is nothing to enable. Every x86_64 CPU still runs the binary — the ones with CET run it with more protection. x64-only per the same docs, which is our only target. -Z deny-partial-mitigations=stack-protector,control-flow-guard — turns a comment into an invariant. The config asserted "build-std rebuilds std with it too, so protection is whole-binary". That was true and unverified. Now the build FAILS if any crate in the graph, std included, is compiled without those mitigations. Partial application is the dangerous case precisely because the binary carries the flag and the reassurance while leaving gaps. Upstream intends this as the default (rust-lang/rust#157941); adopting it now means passing by construction rather than by luck. ENFORCEMENT, not just configuration. CET does NOT live in the optional header's DllCharacteristics like ASLR/DEP/CFG — it travels in a debug-directory entry of type 20 (IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS), so it needed its own reader. CET_COMPAT is now measured structurally and ratcheted with the rest: lose it and the gate fires. Recorded under its own name rather than folded into CONTROL_FLOW_GUARD because the two are independently settable and defend opposite edges — collapsing them would let one vanish while the manifest still looked complete. Verified in both directions, per the #303 lesson: the decoder reports CET_COMPAT absent on every binary built so far (none used the flag), and unit tests pin the positive case, including that an unrelated extended bit must not read as CET. EXPECTED on the next build: the caps gate will fire with "hardening CHANGED: binary has CET_COMPAT, manifest does not declare it". That is the ratchet working; the manifest is deliberately not pre-updated, because it should describe measured reality rather than assert a posture ahead of measuring it. OS-SCOPING, since it was asked: no change needed. These flags live under [target.x86_64-pc-windows-msvc], so they are already applied per-target by construction. A future Linux target would carry its own section and would not inherit any of this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * harden: record CET_COMPAT for hp-thermal — the sign-off on a measured change The caps ratchet fired on the first build with the new flags, as predicted: verify-caps: FAIL - 1 manifest violation(s) for hp-thermal: - hardening CHANGED: binary has CET_COMPAT, manifest does not declare it Three things are established by that single line, none of which were true before: 1. /CETCOMPAT ACTUALLY LANDED. The reader had only ever been exercised in the negative direction, because no binary we had built carried the flag. It now reports the bit on a real artifact, so the positive path is proven on something other than a unit test. 2. deny-partial-mitigations PASSED. The build succeeded, which means every crate in the graph -- std and its dependencies included -- really is compiled with stack-protector and control-flow-guard. The config has claimed whole-binary coverage for a long time; that claim is now machine-checked rather than asserted. 3. The ratchet caught a posture change on the first opportunity, which is what it is for. Recording CET_COMPAT is the sign-off. Exactly ONE violation was reported: the import surface did not move, so the two new flags changed protection without changing what the binary reaches for. Scope note: this covers hp-thermal only. The producer's RUSTFLAGS for the tool fleet do not yet include /CETCOMPAT, so the tools still have forward-edge CFI and no backward edge. Extending it there costs a full producer run and re-bless of all six digests, so it is left as a deliberate follow-up rather than folded in here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Should this be done for Rust 2027 instead? I'm afraid that this may break to many uses now (even though it's an unstable option). |
I don't mind if we break a unstable flag, it is unstable, but you could consider adding an FCW instead for a few releases as an alternative to having this be edition-dependent behaviour |
|
Especially considering the triviality of the fix (pass an extra |
This enables RFC 3855 for stack-protector. With this PR, uses of stack-protector that only have it enabled for a subset of the crates within a process need to pass
-Z allow-partial-mitigations=stack-protectoras well.This was not done in #149357 to allow for a smooth transition period.
cc the stack-protector tracking issue at #114903.
r? @rcvalle (do we need any special protocol for the breaking change?)